home *** CD-ROM | disk | FTP | other *** search
Text File | 1987-02-13 | 8.5 KB | 223 lines | [TEXT/PJMM] |
- UNIT Printing;
-
- INTERFACE
-
- USES
- MacPrint, MyGlobals, Windows;
-
- PROCEDURE DoPrinting;
-
-
- IMPLEMENTATION
-
- {---------Print out a document window-----------}
-
- PROCEDURE DoPrinting;
-
- CONST
- bottommargin = 20;{ margins (in pixels) for document, inset from rPage }
- leftmargin = 30;
- rightmargin = 10;
- topmargin = 36;
-
- VAR
- txth : Handle;
- printTE : TEHandle;
- MyPPort : TPPrPort;
- dlogptr : DialogPtr;
- txtptr : Ptr;
- linesperpage, height, firstoffset, lastoffset, leftpos, toppos, fstpos, lineno, lastline, linecount, pageno, firstpage, lastpage, numpages, copyno, numpasses, dummyitem, errno : INTEGER;
- pagerect : Rect;
- currstr, laststr, heading : Str255;
- strh0, strh1, hdgstrh : StringHandle;
- status : TPrStatus;
- info : FontInfo;
- lastonpage : ARRAY[0..99] OF INTEGER; { last line # on each page }
-
- BEGIN
- { This section images each page, using QuickDraw via TextEdit}
- { A few special cases:}
- { 1. For spooled output (IW only), must image and then print}
- { 2. For IW draft mode, must send multiple copies ourself}
- { This has been completely rewritten from skeleton code, for a number}
- { of key reasons:}
- { 1. A location is calculated for each line and then DrawText is}
- { used to draw the line. This also requires setting the font}
- { directly in the printing GrafPort. The skeleton used TextBox}
- { for each page; TextBox uses an EraseRect which, according to}
- { Technical Note #72, is very slow on the LaserWriter.}
- { 2. We use crOnly, so only actual returns are used for line}
- { breaks. Thus, we don't need a new TECalText for the}
- { printing destRect, but instead use the TextEdit lineStarts}
- { established for display purposes.}
- { 3. This routine figures out what the actual pages selected are,}
- { and then prints only those pages. (The values of prJob.iFstPage}
- { and iLstPage need to be fudged to do this.)}
- { 4. Put a heading on each page, showing page number.}
- { 5. Put up an Alert if a printing error is encountered. Not strictly}
- { necessary, since the most commonly found "errors" are user-}
- { specified aborts that should be ignored.}
- {}
-
- printFlag := FALSE; { so we don't print again }
- DialogueDeactivate;
- IF PrJobDialog(printHdl) THEN
- BEGIN
- SetCursor(watchHdl^^);
- { Put up progress dialog }
- strh0 := GetString(STR_prepare);
- ParamText(strh0^^, '', '', '');
- dlogptr := GetNewDialog(DLOG_printing, NIL, Pointer(-1));
- DrawDialog(dlogptr);
- printTE := hTE;
-
- { Calculate number of pages, and line numbers for each page }
- WITH printTE^^, printHdl^^.PrInfo DO
- BEGIN
- txth := hText;
- height := lineHeight;
- linecount := nLines;
- linesperpage := (rPage.bottom - rPage.top - bottommargin - topmargin) DIV height;
- pagerect := rPage; { top margin allows for heading }
- pagerect.left := pagerect.left + leftmargin;
- pagerect.right := pagerect.right - rightmargin;
- pagerect.bottom := pagerect.top + topmargin + (linesperpage * height);
- fstpos := pagerect.top + topmargin + fontAscent;
- { base line of first line of text in document }
- END; {WITH}
- lastonpage[0] := 0;
- pageno := 1;
- lineno := 0;
- WHILE lineno < linecount DO { until we run out of pages }
- BEGIN
- lineno := lineno + linesperpage;
- IF lineno < linecount THEN { all but last page }
- lastonpage[pageno] := lineno - 1 { last line on this page }
- ELSE { last page }
- lastonpage[pageno] := linecount - 1;{ lines numbered 0..n }
- pageno := pageno + 1;
- END; {WHILE}
- numpages := pageno - 1;
-
- { We could skip page calculations, but then we would image all pages and}
- { Print Manager would print only those selected. Obviously this is}
- { inefficient for large documents. Instead, fool Print Manager into}
- { thinking enough pages are selected and then do actual printing starting}
- { at the selected page. This MUST be done before PrOpenDoc. }
- WITH printHdl^^.PrJob DO
- BEGIN
- firstpage := iFstPage; { page numbers requested }
- IF firstpage < 1 THEN
- firstpage := 1;
- lastpage := iLstPage;
- IF lastpage > numpages THEN
- lastpage := numpages; { limit to available pages }
- numpages := lastpage - firstpage + 1; { actual length }
- iFstPage := 1; { fool print manager }
- iLstPage := numpages; { reset by next PrJobDialog }
- { Manual handling of multiple copies for draft mode only}
- { ImageWriter spooling handles this directly; the LaserWriter PrJobDialog}
- { always sets iCopies := 1 and hides the actual number of copies from us}
- { Also set up appropriate progress message }
- IF bJDocLoop = bSpoolLoop THEN
- BEGIN
- numpasses := 1; { only one pass through }
- strh0 := GetString(STR_spooling);{ "Now spooling " }
- END
- ELSE
- BEGIN
- numpasses := iCopies; { draft mode, multiple passes }
- strh0 := GetString(STR_printing);{ "Now printing " }
- END;
- END; {WITH}
- strh1 := GetString(STR_of); { " of " }
- hdgstrh := GetString(STR_pagehead); { "Page " }
-
- { Now do actual printing (or imaging, for spool mode}
- { Get a drawing port: TPrint should be frozen by now}
- { Go through it once for every copy (if necessary) and once per page }
- { Show dialog progress in terms of pages to be printed }
- MyPPort := PrOpenDoc(printHdl, NIL, NIL);
- NumToString(numpages, laststr); { actual # of pages to print }
- FOR copyno := 1 TO numpasses DO
- BEGIN
- MoveHHi(txth);
- HLock(txth);
- txtptr := txth^;
-
- FOR pageno := firstpage TO lastpage DO
- BEGIN { Image each page; this does printing for draft mode }
- IF PrError = noErr THEN
- BEGIN
- NumToString(pageno - firstpage + 1, currstr); {relative page #}
- ParamText(strh0^^, currstr, strh1^^, laststr);
- DrawDialog(dlogptr); { update the status }
-
- PrOpenPage(MyPPort, NIL); { changes GrafPort for us }
- { First put a heading on the page. Since MoveTo location for drawing text}
- { is the base line, need ascent to position heading within pagerect }
- TextFont(myHdgFont);
- TextSize(myHdgSize);
- GetFontInfo(info); { need ascent height }
- NumToString(pageno, heading); { absolute page number }
- heading := Concat(hdgstrh^^, heading); { "Page 1" }
- WITH pagerect DO
- BEGIN
- leftpos := left + ((right - left - StringWidth(heading)) DIV 2); { center }
- MoveTo(leftpos, top + info.ascent); { base line }
- DrawString(heading); { print page heading }
- { Now print actual document for this page }
- leftpos := left; { left margin for text }
- toppos := fstpos; { base line for 1st line }
- END;
- TextFont(printTE^^.txFont); { set for display }
- TextSize(printTE^^.txSize);
- lineno := lastonpage[pageno - 1];{ line of TERec }
- firstoffset := printTE^^.lineStarts[lineno];
- lastline := lastonpage[pageno];
- { Draw each line in TERec, excluding CR at end of line }
- WHILE lineno <= lastline DO
- BEGIN
- MoveTo(leftpos, toppos);
- lineno := lineno + 1;
- IF lineno >= linecount THEN
- lastoffset := printTE^^.teLength { very last line }
- ELSE
- lastoffset := printTE^^.lineStarts[lineno] - 1;
- DrawText(txtptr, firstoffset, lastoffset - firstoffset);
- toppos := toppos + height;
- firstoffset := lastoffset + 1;
- END; {each line}
- PrClosePage(MyPPort); { done with this page }
- END; {If no Prerror}
- END; {for each page}
-
- HUnLock(txth);
- END; {each copy}
- PrCloseDoc(MyPPort);
- { If spooled, the file is now imaged and now need to print it }
- IF (printHdl^^.prJob.BJDocLoop = BSpoolLoop) AND (PrError = noErr) THEN
- BEGIN
- strh0 := GetString(STR_prspool); { "Now printing spool file" }
- ParamText(strh0^^, '', '', '');
- DrawDialog(dlogptr);
- PrPicFile(printHdl, NIL, NIL, NIL, status);
- END;
- { Drop the advice dialog }
- DisposDialog(dlogptr);
- SetCursor(arrow);
- errno := PrError;
- IF (errno <> noErr) AND (errno <> iPrAbort) AND (errno <> iIOAbort) THEN { indicate a printing error, unless… }
- { user hit command-period }
- { user cancel on "not responding" alert }
- BEGIN
- NumToString(errno, currstr); { error number }
- ParamText(currstr, '', '', ''); { should be more user-friendly }
- dummyitem := StopAlert(ALRT_printerr, NIL);
- END;
- END {IF PrJobDialog}
- ELSE { Cancel in PrJobDlog }
- PrSetError(iPrAbort);
- END; {DoPrinting}
-
- END.